const axios = require('axios');
const { AIModel } = require('../models');

/**
 * AI 分析服务 - 支持多种大模型
 */
class AIAnalysisService {
  constructor() {
    // 默认配置（如果数据库中没有配置）
    this.defaultConfig = {
      baseURL: process.env.AI_BASE_URL || 'https://api.deepseek.com/v1',
      apiKey: process.env.AI_API_KEY || '',
      model: process.env.AI_MODEL || 'deepseek-chat',
      maxTokens: 2000,
      temperature: 0.7,
      timeout: 60000
    };
    
    // 系统提示词
    this.systemPrompt = `你是一位资深的教育学专家，精通中学生学业规划、心理发展和学习策略指导。你坚信每一次考试都是一次诊断，而非最终审判。你的目标是通过分析学生的成绩单，发掘其潜在的兴趣与特长，定位其学习中的困难与挑战，并提供一份充满洞见、具体可行、积极正向的个性化指导报告。

任务 (Task)
你的核心任务是：对下方提供的学生考试成绩单进行全面、深入、富有建设性的分析，并严格按照指定的【分析框架与输出结构】生成一份专业的指导报告。

分析框架与输出结构 (Analysis Framework & Output Structure)
请严格遵循以下步骤和结构，确保报告的专业性、逻辑性和可读性。

第一部分：成绩概览与数据整理
基本信息呈现：清晰地罗列出学生的姓名、年级、考试名称等基本信息。
成绩表格化：以清晰的表格形式展示所有科目的名称和分数。
学科强弱分析：在表格旁或下方，明确标注出该学生的"优势学科"、"中等学科"和"薄弱/亟待提升学科"。

第二部分：核心洞察与深度解读
在这一部分，你需要超越分数的表面，进行深层分析：
识别学科群表现：分析学生在"文科"（如语文、历史、政治）与"理科"（如数学、物理、化学）两大类学科群中的整体表现差异，并进行对比。
推断潜在能力特质：基于学科表现，推断学生可能具备的底层能力。例如：
语文/历史成绩好 -> 可能意味着较强的语言理解、逻辑思辨、文字表达和共情能力。
数学/物理成绩好 -> 可能意味着较强的逻辑推理、空间想象和抽象思维能力。
化学/生物成绩差 -> 可能反映出在知识记忆、归纳总结或实验探究方面存在困难。
英语成绩差 -> 要特别关注是词汇、语法等基础问题，还是阅读、写作等综合应用问题。
综合诊断：总结学生当前学业状况的核心特点，例如"文科素养突出，理科基础存在短板"、"逻辑思维尚可，但记忆型学科掌握不佳"等。

第三部分：未来学习与发展指导建议
这是报告的核心，所有建议必须具体、可操作。
扬长策略 (巩固优势)：针对学生的优势学科，提出如何"从优秀到卓越"的进阶建议。例如，推荐相关书籍、参加竞赛、拓展项目式学习等，将优势转化为真正的"特长"。
补短策略 (攻克弱项)：针对学生的薄弱学科，给出清晰的"拯救计划"。建议必须具体，避免"多努力"之类的空话。例如：
对于基础极其薄弱的学科（如20-30分）：建议"回归课本"，从最基础的概念和公式入手，寻求老师或同学的"一对一"辅导。
对于中等偏下的学科：建议从"整理错题"、"强化专题训练"等着手。
学习方法与习惯调整：提供1-2条跨学科的通用学习建议，如时间管理技巧、预习复习方法、笔记系统构建等。
未来路径规划 (选科/发展方向)：基于本次成绩分析，对未来的高中选科（如新高考"3+1+2"组合）提出初步的、探索性的建议，并强调这只是参考，鼓励学生在接下来的学习中继续探索兴趣。

第四部分：寄语与鼓励 (面向不同对象)
对学生说：用鼓励、平等的语气，肯定其亮点，帮助其正视问题，并激发其内在学习动力。强调单次考试的局限性和未来发展的无限可能性。
对家长说：建议家长如何理性看待分数，如何与孩子进行有效沟通，以及如何配合学校和孩子共同制定改进计划。强调家庭支持和积极心态的重要性。

核心原则 (Core Principles)
积极正向：你的语言风格必须是建设性和鼓励性的，避免使用打击性或过于绝对的评判词汇。
数据驱动：所有的分析和建议都必须紧密围绕提供的成绩数据展开，做到有据可依。
具体可行：避免空泛的口号，提供的建议要让学生和家长看完后知道"下一步该做什么"。
全面视角：在报告开头或结尾处，应提及"单次月考成绩具有局限性，它更多地反映了近期的学习状态和对知识的阶段性掌握情况，需要结合学生平时的表现和长期兴趣综合判断"。`;
  }

  /**
   * 获取激活的模型配置
   * @returns {Promise<Object>} 模型配置
   */
  async getActiveModelConfig() {
    try {
      const activeModel = await AIModel.findOne({
        where: { is_active: true }
      });

      if (activeModel) {
        return {
          baseURL: activeModel.base_url,
          apiKey: activeModel.api_key,
          model: activeModel.model_name,
          maxTokens: activeModel.max_tokens,
          temperature: activeModel.temperature,
          timeout: activeModel.timeout
        };
      }

      // 如果没有激活的模型，使用默认配置
      console.warn('未找到激活的模型配置，使用默认配置');
      return this.defaultConfig;
    } catch (error) {
      console.error('获取模型配置失败:', error);
      return this.defaultConfig;
    }
  }

  /**
   * 生成学生成绩分析报告（带重试机制）
   * @param {Object} studentData - 学生成绩数据
   * @returns {Promise<string>} 分析报告
   */
  async generateAnalysisReport(studentData) {
    const maxRetries = 3; // 最多重试3次
    let lastError = null;

    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        console.log(`[尝试 ${attempt}/${maxRetries}] 开始生成分析报告...`);
        
        // 获取激活的模型配置
        const config = await this.getActiveModelConfig();

        if (!config.apiKey) {
          throw new Error('未配置 AI 模型，请联系管理员在后台配置');
        }

        // 构建用户消息
        const userMessage = this.buildUserMessage(studentData);
        
        console.log(`使用模型: ${config.model}, API: ${config.baseURL}`);
        
        // 调用 AI API（增加超时时间到120秒）
        const response = await axios.post(
          `${config.baseURL}/chat/completions`,
          {
            model: config.model,
            messages: [
              {
                role: 'system',
                content: this.systemPrompt
              },
              {
                role: 'user',
                content: userMessage
              }
            ],
            temperature: config.temperature,
            max_tokens: config.maxTokens,
            stream: false
          },
          {
            headers: {
              'Authorization': `Bearer ${config.apiKey}`,
              'Content-Type': 'application/json'
            },
            timeout: Math.max(config.timeout, 120000), // 至少120秒
            maxContentLength: Infinity,
            maxBodyLength: Infinity,
            // 添加重试配置
            validateStatus: (status) => status < 500 // 只有5xx错误才会抛出异常
          }
        );

        // 检查响应状态
        if (response.status >= 400) {
          const errorMsg = response.data?.error?.message || response.data?.message || '未知错误';
          throw new Error(`API返回错误 (${response.status}): ${errorMsg}`);
        }

        if (response.data && response.data.choices && response.data.choices.length > 0) {
          console.log(`[成功] 分析报告生成成功`);
          return response.data.choices[0].message.content;
        } else {
          throw new Error('AI 返回数据格式异常');
        }
      } catch (error) {
        lastError = error;
        
        // 判断错误类型
        const isTimeout = error.code === 'ECONNABORTED' || error.message.includes('timeout');
        const isNetworkError = error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED' || error.code === 'ETIMEDOUT';
        const is5xxError = error.response && error.response.status >= 500;
        
        // 记录详细错误信息
        console.error(`[失败 ${attempt}/${maxRetries}] AI 分析失败:`, error.message);
        if (error.response) {
          console.error('API 错误详情:', {
            status: error.response.status,
            data: error.response.data
          });
        }
        
        // 如果是最后一次尝试，或者是不可重试的错误，直接抛出
        if (attempt === maxRetries || (!isTimeout && !isNetworkError && !is5xxError)) {
          // 提供更友好的错误信息
          let friendlyMessage = '生成分析报告失败';
          
          if (isTimeout) {
            friendlyMessage = 'AI服务响应超时，请稍后重试';
          } else if (isNetworkError) {
            friendlyMessage = '无法连接到AI服务，请检查网络连接';
          } else if (error.response?.status === 401) {
            friendlyMessage = 'AI服务认证失败，请联系管理员检查配置';
          } else if (error.response?.status === 429) {
            friendlyMessage = 'AI服务请求过于频繁，请稍后重试';
          } else if (error.response?.data?.error?.message) {
            friendlyMessage = `AI服务错误: ${error.response.data.error.message}`;
          }
          
          throw new Error(friendlyMessage);
        }
        
        // 等待后重试（指数退避）
        const waitTime = Math.min(1000 * Math.pow(2, attempt - 1), 5000); // 1s, 2s, 4s
        console.log(`等待 ${waitTime}ms 后重试...`);
        await new Promise(resolve => setTimeout(resolve, waitTime));
      }
    }
    
    // 理论上不会到这里，但为了安全
    throw lastError || new Error('生成分析报告失败');
  }

  /**
   * 生成学生成绩分析报告（流式输出）
   * @param {Object} studentData - 学生成绩数据
   * @param {Function} onChunk - 接收每个数据块的回调函数
   * @returns {Promise<void>}
   */
  async generateAnalysisReportStream(studentData, onChunk) {
    try {
      // 获取激活的模型配置
      const config = await this.getActiveModelConfig();

      if (!config.apiKey) {
        throw new Error('未配置 AI 模型，请联系管理员在后台配置');
      }

      // 构建用户消息
      const userMessage = this.buildUserMessage(studentData);
      
      console.log(`[流式] 使用模型: ${config.model}, API: ${config.baseURL}`);
      
      // 调用 AI API（流式模式）
      const response = await axios.post(
        `${config.baseURL}/chat/completions`,
        {
          model: config.model,
          messages: [
            {
              role: 'system',
              content: this.systemPrompt
            },
            {
              role: 'user',
              content: userMessage
            }
          ],
          temperature: config.temperature,
          max_tokens: config.maxTokens,
          stream: true // 启用流式输出
        },
        {
          headers: {
            'Authorization': `Bearer ${config.apiKey}`,
            'Content-Type': 'application/json'
          },
          timeout: 120000,
          responseType: 'stream' // 接收流式响应
        }
      );

      // 处理流式响应
      return new Promise((resolve, reject) => {
        let buffer = '';
        
        response.data.on('data', (chunk) => {
          const lines = chunk.toString().split('\n').filter(line => line.trim() !== '');
          
          for (const line of lines) {
            const message = line.replace(/^data: /, '');
            
            if (message === '[DONE]') {
              resolve();
              return;
            }
            
            try {
              const parsed = JSON.parse(message);
              const content = parsed.choices?.[0]?.delta?.content;
              
              if (content) {
                onChunk(content);
              }
            } catch (e) {
              // 忽略解析错误，继续处理下一行
            }
          }
        });
        
        response.data.on('end', () => {
          console.log('[流式] 报告生成完成');
          resolve();
        });
        
        response.data.on('error', (error) => {
          console.error('[流式] 错误:', error);
          reject(error);
        });
      });
      
    } catch (error) {
      console.error('[流式] AI 分析失败:', error.message);
      throw new Error(`生成分析报告失败: ${error.message}`);
    }
  }

  /**
   * 构建发送给 AI 的用户消息
   * @param {Object} studentData - 学生成绩数据
   * @returns {string} 格式化的消息
   */
  buildUserMessage(studentData) {
    const { name, className, scores } = studentData;
    
    let message = `请为以下学生生成成绩分析报告：\n\n`;
    message += `学生姓名：${name}\n`;
    message += `班级：${className}\n\n`;
    message += `成绩记录：\n`;
    
    scores.forEach((score, index) => {
      message += `\n【考试 ${index + 1}】\n`;
      message += `考试名称：${score.examName}\n`;
      message += `考试日期：${score.examDate}\n`;
      message += `各科成绩：\n`;
      
      const subjects = [
        { name: '语文', value: score.chinese },
        { name: '数学', value: score.math },
        { name: '英语', value: score.english },
        { name: '物理', value: score.physics },
        { name: '化学', value: score.chemistry },
        { name: '生物', value: score.biology },
        { name: '政治', value: score.politics },
        { name: '历史', value: score.history },
        { name: '地理', value: score.geography }
      ];
      
      subjects.forEach(subject => {
        if (subject.value !== null && subject.value !== undefined && subject.value !== '') {
          message += `  ${subject.name}：${subject.value}分\n`;
        }
      });
      
      if (score.totalScore) {
        message += `  总分：${score.totalScore}分\n`;
      }
      if (score.schoolRank) {
        message += `  校次：${score.schoolRank}\n`;
      }
    });
    
    message += `\n请根据以上成绩数据，生成一份详细的分析报告。`;
    
    return message;
  }
}

module.exports = new AIAnalysisService();
